package com.iot.utils;

import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.commons.lang3.time.DateUtils;

import java.text.ParseException;
import java.util.Calendar;
import java.util.Date;

public class DateUtil {

    public static final String YYYY_MM_DD = "yyyy-MM-dd";

    public static final String YYYY_MM = "yyyy-MM";

    public static final String YYYYMM = "yyyyMM";

    public static final String yyyy_mm_dd_HH_mm_ss = "yyyy-MM-dd HH:mm:ss";

    public static final String chineseYYYYMMDD = "yyyy年MM月dd日";

    public static final String chineseYYYYMMDDHHMM = "yyyy年MM月dd日HH点mm分";

    public static final String chineseMMDD = "MM月dd日";

    public static final String YYYYMMDD = "yyyy.MM.dd";

    public static final String DATE = "yyyyMMdd";

    public static final String HHMM = "HH:mm";

    public static final String YYYY = "yyyy";

    public static final String MM = "MM";

    public static final String mm = "mm";

    public static final String DD = "dd";

    public static final String HH = "HH";

    public static Date now() {
        return new Date();
    }

    public static long nowSecond() {
        return new Date().getTime()/1000;
    }

    public static long getSecond(Date date) {
        return null == date ? 0L : date.getTime()/1000;
    }

    public static Date parseDate(String str) {
        try {
            return DateUtils.parseDate(str, yyyy_mm_dd_HH_mm_ss);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static String formatDateToDay(Date date, String format) {
        if (null == date) {
            return "";
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.HOUR_OF_DAY,8);
        return DateFormatUtils.format(calendar.getTime(), format);
    }

    public final static Date stringToDateByDay(String date, String format) {
        try {
            return DateUtils.parseDate(date, format);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    public final static Date stringToDateByDay(String date) {
        try {
            return DateUtils.parseDate(date, YYYYMMDD);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static Date addDay(Date date, int amount) {
        return DateUtils.addDays(date, amount);
    }

    public static Date addMinutes(Date date, int amount) {
        return DateUtils.addMinutes(date, amount);
    }

    /**
     * 日期转星期
     *
     * @param date
     * @return
     */
    public static String dateToWeek(Date date) {
        if (null == date) {
            return "";
        }
        String[] weekDays = {"日", "一", "二", "三", "四", "五", "六"};
        Calendar cal = Calendar.getInstance(); // 获得一个日历
        cal.setTime(date);
        int w = cal.get(Calendar.DAY_OF_WEEK) - 1; // 指示一个星期中的某天。
        if (w < 0) {
            w = 0;
        }
        return weekDays[w];
    }

    public static Date addDateOfField(Date date, String pattern, int amount) {
        if (pattern.equals(YYYY)) {
            date = DateUtils.addYears(date, amount);
        } else if (pattern.equals(MM)) {
            date = DateUtils.addMonths(date, amount);
        } else if (pattern.equals(DD)) {
            date = DateUtils.addDays(date, amount);
        } else if (pattern.equals(HH)) {
            date = DateUtils.addHours(date, amount);
        } else if (pattern.equals(mm)) {
            date = DateUtils.addMinutes(date, amount);
        } else if (pattern.equals("ss")) {
            date = DateUtils.addSeconds(date, amount);
        } else if (pattern.equals("SSS")) {
            date = DateUtils.addMilliseconds(date, amount);
        }
        return date;
    }

    /**
     * 获取开始时间 00:00:00
     *
     * @return
     */
    public static Date getDayStart(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return cal.getTime();
    }


    /**
     * 获取开始时间 00:00:00
     *
     * @return
     */
    public static Date getMinuteStart(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return cal.getTime();
    }


    /**
     * 获取开始时间 00:00:00
     *
     * @return
     */
    public static Date getMinuteEnd(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.SECOND, 59);
        cal.set(Calendar.MINUTE, 59);
        cal.set(Calendar.MILLISECOND, 0);
        return cal.getTime();
    }

    /**
     * 获取开始时间 00:00:00
     *
     * @return
     */
    public static Date getMonthStart(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.DAY_OF_MONTH, 1);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return cal.getTime();
    }

    /**
     * 获取年开始时间 00:00:00
     *
     * @return
     */
    public static Date getYearStart(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.MONTH, 0);
        cal.set(Calendar.DAY_OF_MONTH, 1);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return cal.getTime();
    }

    public static Date getYearEnd(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.MONTH, 12);
        cal.set(Calendar.DAY_OF_MONTH, 0);
        cal.set(Calendar.HOUR_OF_DAY, 23);
        cal.set(Calendar.SECOND, 59);
        cal.set(Calendar.MINUTE, 59);
        //适配mysql版本，对时间类型的数据毫秒四舍五入进一导致日期进1 bug
        cal.set(Calendar.MILLISECOND, 0);
        return cal.getTime();
    }


    // 返回传入月的最后一天时间
    public static Date getMonthEnd(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.MONTH, 1);
        cal.set(Calendar.DAY_OF_MONTH, 0);
        cal.set(Calendar.HOUR_OF_DAY, 23);
        cal.set(Calendar.SECOND, 59);
        cal.set(Calendar.MINUTE, 59);
        //适配mysql版本，对时间类型的数据毫秒四舍五入进一导致日期进1 bug
        cal.set(Calendar.MILLISECOND, 0);
        return cal.getTime();
    }

    // 返回传入月的最后一天时间
    public static Date getStartDayOfMonth(Date date,int day) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        if (day == 0) {
            cal.add(Calendar.MONTH, 1);
        }
        cal.set(Calendar.DAY_OF_MONTH, day);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MINUTE, 0);
        //适配mysql版本，对时间类型的数据毫秒四舍五入进一导致日期进1 bug
        cal.set(Calendar.MILLISECOND, 0);
        return cal.getTime();
    }


    // 返回传入月的最后一天时间
    public static Date getEndDayOfMonth(Date date,int day) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        if (day == 0) {
            cal.add(Calendar.MONTH, 1);
        }
        cal.set(Calendar.DAY_OF_MONTH, day);
        cal.set(Calendar.HOUR_OF_DAY, 23);
        cal.set(Calendar.SECOND, 59);
        cal.set(Calendar.MINUTE, 59);
        //适配mysql版本，对时间类型的数据毫秒四舍五入进一导致日期进1 bug
        cal.set(Calendar.MILLISECOND, 0);

        if (day == 0) {
            cal.add(Calendar.HOUR_OF_DAY, -8);
        }
        return cal.getTime();
    }

    /**
     * 获取开始时间 23:59:59
     *
     * @return
     */
    public static Date getDayEnd(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.HOUR_OF_DAY, 23);
        cal.set(Calendar.SECOND, 59);
        cal.set(Calendar.MINUTE, 59);
        cal.set(Calendar.MILLISECOND, 59);
        return cal.getTime();
    }

    public static int age(Date birthDate) {
        // 当前日历
        Calendar nowCalendar = Calendar.getInstance();
        // 生日大于当前日期
        if (nowCalendar.before(birthDate)) {
            throw new IllegalArgumentException("The birth date is before current time, it's unbelievable");
        }
        // 当前年月日
        int yearNow = nowCalendar.get(Calendar.YEAR);
        int monthNow = nowCalendar.get(Calendar.MONTH);
        int dayNow = nowCalendar.get(Calendar.DAY_OF_MONTH);
        // 出生日期年月日
        Calendar birthCalendar = Calendar.getInstance();
        birthCalendar.setTime(birthDate);
        int yearBirth = birthCalendar.get(Calendar.YEAR);
        int monthBirth = birthCalendar.get(Calendar.MONTH);
        int dayBirth = birthCalendar.get(Calendar.DAY_OF_MONTH);
        // 粗计算年龄
        int age = yearNow - yearBirth;
        // 当前月份小于出生月份年龄减一
        if (monthNow < monthBirth) {
            age--;
        }
        // 当前月份等于出生月份，日小于生日年龄减一
        else if (monthNow == monthBirth && dayNow < dayBirth) {
            age--;
        }
        // 返回年龄值
        return age;
    }

    public static int getDifferHour(Date startDate, Date endDate) {
        long dayM = 1000 * 24 * 60 * 60;
        long hourM = 1000 * 60 * 60;
        long differ = endDate.getTime() - startDate.getTime();
        long hour = differ % dayM / hourM + 24 * (differ / dayM);
        return Integer.parseInt(String.valueOf(hour));
    }

    /**
     * 获取当年的开始时间
     */
    public static Date getYearStartTime(Date date) {
        Calendar calendar = Calendar.getInstance();// 获取当前日期
        calendar.setTime(date);
        calendar.add(Calendar.YEAR, 0);
        calendar.add(Calendar.DATE, 0);
        calendar.add(Calendar.MONTH, 0);
        calendar.set(Calendar.DAY_OF_YEAR, 1);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }

}
